<template>
    <div class="wh-100% flex flex-col gap-2.5">
        <n-card>
            <n-form label-placement="left" :show-feedback="false">
                <n-grid :cols="4" :x-gap="30">
                    <n-form-item-gi label="用户id">
                        <n-input v-model:value="searchContent.userId"></n-input>
                    </n-form-item-gi>
                    <n-form-item-gi label="请求时间">
                        <n-date-picker
                            v-model:value="daterange"
                            type="daterange"
                            clearable
                        />
                    </n-form-item-gi>
                </n-grid>
            </n-form>
            <div class="w-full flex justify-end gap-10px">
                <n-button :focusable="false" @click="handleResetConditions">
                    <template #icon>
                        <n-icon :component="Reload" />
                    </template>
                    重置
                </n-button>
                <n-button :focusable="false" @click="handleSubmitConditions">
                    <template #icon>
                        <n-icon :component="Search" />
                    </template>
                    查找
                </n-button>
            </div>
        </n-card>
        <n-card class="flex-1">
            <template #header>
                <div class="w-full flex justify-between">
                    <div>预测记录列表</div>
                    <n-button :focusable="false" @click="handleReset">
                        <template #icon>
                            <n-icon :component="Reload" />
                        </template>
                        刷新
                    </n-button>
                </div>
            </template>
            <div
                v-if="currentPredictions.length === 0"
                class="wh-100% flex-center"
            >
                <n-result status="403" title="暂无数据"> </n-result>
            </div>
            <n-data-table
                v-else
                :columns="
                    userPredictionColumns(
                        handleDeletePrediction,
                        handleDownloadPrediction,
                        handleCheckPrediction
                    )
                "
                :data="currentPredictions"
                :scroll-x="1800"
            ></n-data-table>
            <template #footer>
                <div class="w-full flex justify-between">
                    <span>共 {{ pagination.total }} 条</span>
                    <n-pagination
                        :total="pagination.total"
                        :page-size="pagination.size"
                    />
                </div>
            </template>
        </n-card>
        <n-drawer
            v-model:show="fileDetailDrawerShow"
            :auto-focus="false"
            width="800"
        >
            <n-drawer-content>
                <template #header>文件详情</template>
                <FileDetail :file-path="activeFilePath" />
            </n-drawer-content>
        </n-drawer>
    </div>
</template>

<script lang="ts" setup>
import { ref, reactive, watch, onMounted } from "vue";

import { Reload, Search } from "@vicons/ionicons5";

import { userPredictionColumns } from "@/utils/table-column";

import { UserPrediction } from "@/types/prediction";
import { UserPredictionSearchDto } from "@/service/api/dto/predict.dto";

import { throttle } from "radash";
import {
    getUserPredictions,
    saveFileToLocal,
    deleteUserPrediction,
} from "@/service/api/predict";

import FileDetail from "./components/file-detail/index.vue";

const daterange = ref<[number, number] | null>(null);
const emptySearchContent: UserPredictionSearchDto = {
    userId: null,
    startDate: null,
    endDate: null,
};
const searchContent = reactive<UserPredictionSearchDto>(
    structuredClone(emptySearchContent)
);
let searchConditions: Partial<UserPredictionSearchDto> | null = null;

const pagination = reactive({
    page: 1,
    size: 10,
    total: 100,
});
const predictions = new Map<number, UserPrediction[]>();
const currentPredictions = ref<UserPrediction[]>([]);

const activeFilePath = ref("");
const fileDetailDrawerShow = ref(false);

const handleQuery = async () => {
    try {
        const res = await getUserPredictions(
            pagination.page,
            pagination.size,
            searchConditions ?? {}
        );
        pagination.total = res.count;
        currentPredictions.value = res.files;
        predictions.set(pagination.page, res.files);

        pagination.page++;
    } catch (err) {
        window.NMessage.error((err as Error).message);
    }
};

const handleReset = async () => {
    pagination.page = 1;
    pagination.size = 10;

    predictions.clear();
    currentPredictions.value = [];

    await handleQuery();
};

watch(daterange, (val) => {
    if (val) {
        searchContent.startDate = val[0];
        searchContent.endDate = val[1];
    } else {
        searchContent.startDate = null;
        searchContent.endDate = null;
    }
});

onMounted(async () => {
    await handleQuery();
});

const handleCheckPrediction = (path: string) => {
    activeFilePath.value = path;
    fileDetailDrawerShow.value = true;
};

const handleDeletePrediction = (id: string) => {
    window.NDialog.warning({
        title: "删除预测",
        content: "确定删除该预测吗？",
        closable: false,
        positiveText: "删除",
        negativeText: "取消",
        onPositiveClick: async () => {
            try {
                await deleteUserPrediction(id);

                handleReset();
                window.NMessage.success("删除成功");
            } catch (err) {
                window.NMessage.error((err as Error).message);
            }
        },
    });
};

const handleDownloadPrediction = async (path: string) => {
    try {
        await saveFileToLocal(path);
        window.NMessage.success("下载成功");
    } catch (err) {
        window.NMessage.error((err as Error).message || "下载失败");
    }
};

const handleResetConditions = () => {
    Object.assign(searchContent, structuredClone(emptySearchContent));
    daterange.value = null;

    if (!searchConditions) return;
    searchConditions = null;
    handleReset();
};

const handleSubmitConditions = throttle({ interval: 1000 }, () => {
    if (JSON.stringify(emptySearchContent) === JSON.stringify(searchContent)) {
        window.NMessage.warning("请输入搜索条件");
        return;
    }
    searchConditions = Object.fromEntries(
        Object.entries(searchContent).filter(
            ([_, value]) => value !== null && value !== ""
        )
    );
    debugger;
    handleReset();
});
</script>

<style scoped></style>
